/**
 * @file raster_planner.h
 * @copyright Copyright (c) 2021, Southwest Research Institute
 *
 * @par License
 * Software License Agreement (Apache License)
 * @par
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * @par
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once  // 防止头文件被多重包含

#include <memory>  // 引入智能指针的头文件

#include <noether_tpp/core/tool_path_modifier.h>  // 引入工具路径修改器头文件
#include <noether_tpp/core/tool_path_planner.h>  // 引入工具路径规划器头文件

namespace noether  // 定义命名空间 noether
{
/**
 * @brief Interface for various methods to generate the direction of raster paths.  The direction
 * generated will move along the line from the first point to the second, then third, etc.
 * 
 * 这个结构体是用于生成栅格路径方向的接口，方向会依次从第一个点到第二个点，第三个点等。
 */
struct DirectionGenerator
{
  using Ptr = std::unique_ptr<DirectionGenerator>;  // 定义智能指针类型 Ptr
  using ConstPtr = std::unique_ptr<const DirectionGenerator>;  // 定义常量智能指针类型 ConstPtr

  virtual ~DirectionGenerator() = default;  // 虚析构函数，确保派生类对象能正确析构
  virtual Eigen::Vector3d generate(const pcl::PolygonMesh& mesh) const = 0;  // 纯虚函数，用于生成方向
};

/**
 * @brief Interface for setting the start point from which to generate toolpaths
 * 
 * 该结构体是用于设置起始点以生成工具路径的接口。
 */
struct OriginGenerator
{
  using Ptr = std::unique_ptr<OriginGenerator>;  // 定义智能指针类型 Ptr
  using ConstPtr = std::unique_ptr<const OriginGenerator>;  // 定义常量智能指针类型 ConstPtr

  virtual ~OriginGenerator() = default;  // 虚析构函数
  virtual Eigen::Vector3d generate(const pcl::PolygonMesh& mesh) const = 0;  // 纯虚函数，用于生成起始点
};

/**
 * @brief A specification of the tool path planner for covering surfaces
 * in repeating, evenly spaced path lines.  By default, a raster planner will produce a path with
 * all points having a consistent orientation, lines which all travel in the same direction across
 * the surface, and the traversal between lines will be in a consistent direction and order.
 * 
 * 这是一个用于生成重复且均匀分布路径线的工具路径规划器的规格。栅格路径规划器的默认行为是生成一条路径，其中所有点具有一致的方向，
 * 所有路径行在表面上沿相同方向行进，行与行之间的遍历顺序也一致。
 */
class RasterPlanner : public ToolPathPlanner  // RasterPlanner 类继承自 ToolPathPlanner 基类
{
public:
  /**
   * @brief 构造函数，接受方向生成器和原点生成器
   * 
   * @param dir_gen 方向生成器（生成路径方向的工具）
   * @param origin_gen 起始点生成器（生成路径起始点的工具）
   */
  RasterPlanner(DirectionGenerator::ConstPtr dir_gen, OriginGenerator::ConstPtr origin_gen);

  // 覆盖基类的计划函数，生成工具路径
  ToolPaths plan(const pcl::PolygonMesh& mesh) const override final;

  // 设置路径点之间的间距
  void setPointSpacing(const double point_spacing);
  // 设置栅格路径行之间的间距
  void setLineSpacing(const double line_spacing);
  // 设置最小孔洞大小，表示在规划路径时，遇到该尺寸以下的孔洞时不进行路径分割
  void setMinHoleSize(const double min_hole_size);

protected:
  /**
   * @brief 具体的工具路径规划实现函数
   * 
   * @param mesh 输入的多边形网格（表示需要规划路径的表面）
   * @return 返回生成的工具路径
   */
  virtual ToolPaths planImpl(const pcl::PolygonMesh& mesh) const = 0;

  DirectionGenerator::ConstPtr dir_gen_;  // 存储方向生成器的常量智能指针
  OriginGenerator::ConstPtr origin_gen_;  // 存储原点生成器的常量智能指针

  /** @brief 路径点之间的间距（单位：米） */
  double point_spacing_;
  /** @brief 栅格路径行之间的间距（单位：米） */
  double line_spacing_;
  /** @brief 孔洞的最小尺寸，表示当路径线跨越一个小于该尺寸的孔洞时，路径将被拆分成多个段 */
  double min_hole_size_;
};

/**
 * @brief Interface for creating implementations of raster tool path planners.
 * @details This class contains the generic parameters for configuring raster tool path planners
 * 
 * 这个结构体是用于创建栅格工具路径规划器实现的接口，包含了一些通用的配置参数。
 */
struct RasterPlannerFactory : public ToolPathPlannerFactory  // RasterPlannerFactory 类继承自 ToolPathPlannerFactory 基类
{
  /** @brief 路径点之间的间距（单位：米） */
  double point_spacing;
  /** @brief 栅格路径行之间的间距（单位：米） */
  double line_spacing;
  /** @brief 孔洞的最小尺寸，表示当路径线跨越一个小于该尺寸的孔洞时，路径将被拆分成多个段 */
  double min_hole_size;
  /** @brief 创建栅格方向生成器的函数 */
  std::function<std::unique_ptr<const DirectionGenerator>()> direction_gen;
  /** @brief 创建栅格原点生成器的函数 */
  std::function<std::unique_ptr<const OriginGenerator>()> origin_gen;
};

}  // namespace noether  // 结束 noether 命名空间